/**
 * 
 */
package com.zufangbao.earth.handler.impl;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jsoup.Connection.Method;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.demo2do.core.entity.Result;
import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.web.resolver.Page;
import com.zufangbao.earth.handler.ReceivableHandler;
import com.zufangbao.earth.service.AppParticlesService;
import com.zufangbao.earth.service.ContractParticalService;
import com.zufangbao.earth.service.ParticalService;
import com.zufangbao.gluon.api.earth.ParticleModelConfigEnum;
import com.zufangbao.gluon.api.earth.ReceivablesBrief;
import com.zufangbao.gluon.api.earth.TransferStatus;
import com.zufangbao.gluon.api.quark.ApiSpecBillDeposite.IGetReceivablesBrief;
import com.zufangbao.gluon.api.quark.ApiSpecBillDeposite.INotReachPaymentDateBills;
import com.zufangbao.gluon.api.quark.ApiSpecBillDeposite.IOutstandingBills;
import com.zufangbao.gluon.api.quark.ApiSpecBillDeposite.IOverPaymentDateBills;
import com.zufangbao.gluon.api.quark.ApiSpecBillDeposite.ITodayPaidBills;
import com.zufangbao.gluon.api.quark.ApiSpecBillDeposite.ITodayUnpaidOutstandingBills;
import com.zufangbao.gluon.api.quark.ApiSpecBillDeposite.ITransactionConfirm;
import com.zufangbao.gluon.api.quark.ApiSpecBillDeposite.ITransactionsFromBills;
import com.zufangbao.gluon.api.quark.AuthorisedBillSketch;
import com.zufangbao.gluon.api.quark.TransactionRecordSketch;
import com.zufangbao.gluon.exception.CommonException;
import com.zufangbao.gluon.spec.earth.GlobalSpec4Earth;
import com.zufangbao.gluon.spec.earth.GlobalSpec4Earth.ErrorCode4AutorisedBillSketch;
import com.zufangbao.gluon.spec.global.GlobalCodeSpec;
import com.zufangbao.gluon.spec.global.GlobalCodeSpec.GeneralErrorCode;
import com.zufangbao.sun.entity.order.Order;
import com.zufangbao.sun.entity.receivables.HistoryPaidType;
import com.zufangbao.sun.service.AppService;
import com.zufangbao.sun.service.ContractService;
import com.zufangbao.sun.service.OrderService;

/**
 * @author wukai
 *
 */
@Component("quarkReceivableHandler")
public class QuarkReceivableHandlerImpl implements ReceivableHandler {

	@Autowired
	private ParticalService particalService;
	
	@Autowired
	private AppParticlesService appParticlesService;
	
	@Autowired
	private ContractService contractService;
	
	@Autowired
	private ContractParticalService contractParticalService;
	
	@Autowired
	private OrderService orderService;
	
	@Autowired
	private AppService appService;
	
	@Autowired
	private GenericDaoSupport genericDaoSupport;
	
	@Value("#{config['timeout']}")
	private int TIMEOUT;
	
	private static final Log logger = LogFactory.getLog(QuarkReceivableHandlerImpl.class);
	
	@SuppressWarnings("unchecked")
	@Override
	public List<Order> getHistoryPaidOrder(String appId,
			String particalUniqueId, String contractNo,
			HistoryPaidType historyPaidType, Page page) throws CommonException {
		
		if(org.springframework.util.StringUtils.isEmpty(appId)){
			
			throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
		}
		
		int begin = page.getBeginIndex();
		
		int max = page.getMaxResultRecords();
		
		if(begin < 0 || max < 0 ){
			
			throw new CommonException(ErrorCode4AutorisedBillSketch.ERROR_BEGIN_OR_MAX_INVALID);
		}
		
		List<Order> orderList = orderService.getHistoryPaidOrderAtQuark(appId, particalUniqueId, contractNo, historyPaidType, page.getBeginIndex(), page.getMaxResultRecords());
		
		page.calculate(orderList.size());
		
		return orderList.size() > page.getEveryPage() ? orderList.subList(0, page.getEveryPage()) : orderList;
	}

	@Override
	public List<AuthorisedBillSketch> getTodayPaidBill(String appId, String particalUniqueId, Page page) throws CommonException {
		
		if(org.springframework.util.StringUtils.isEmpty(appId)){
			
			throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
		}
		
		int begin = page.getBeginIndex();
		
		int max = page.getMaxResultRecords();
		
		if(begin < 0 || max < 0 ){
			
			throw new CommonException(ErrorCode4AutorisedBillSketch.ERROR_BEGIN_OR_MAX_INVALID);
		}
		
		String todayPaidBillApiName = ParticleModelConfigEnum.CONFIG_KEY_API_GET_TODAY_PAID_BILLS.getAlias();
		
		String todayPaidBillApiUrl = particalService.getQuarkApIUrl(particalUniqueId, todayPaidBillApiName);
		
		logger.info("begin to get the today paid bills with appId["+appId+"],begin["+begin+"],max=["+max+"],the api url["+todayPaidBillApiUrl+"]");
		
		try {
		
			Response response = Jsoup.connect(todayPaidBillApiUrl)
									 .method(Method.GET)
									 .data(ITodayPaidBills.PARAM_APPID,appId)
									 .data(ITodayPaidBills.PARAM_BEGIN,String.valueOf(begin))
									 .data(ITodayPaidBills.PARAM_MAX,String.valueOf(max))
									 .timeout(TIMEOUT)
									 .execute();
			
			logger.info("get the today paid bills result[" + response.body() + "]");
			
			Result result = JsonUtils.parse(response.body(), Result.class);
			
			List<AuthorisedBillSketch> authorisedBillSketchs = (List<AuthorisedBillSketch>) result.getData().get(ITodayPaidBills.RET_BILLS);
			
			page.calculate(authorisedBillSketchs.size());
			
			return authorisedBillSketchs.size() > page.getEveryPage() ? authorisedBillSketchs.subList(0, page.getEveryPage()) : authorisedBillSketchs; 
			
		} catch (Exception e) {
			
			logger.info("get the today paid bills error : " + e.getMessage());
			
			throw new CommonException(GeneralErrorCode.ERROR_SYSTEM);
		}
	}

	@Override
	public List<AuthorisedBillSketch> getTodayUnpaidOutstandingBill(String appId,
			String particalUniqueId, Page page) throws CommonException {
		if(StringUtils.isEmpty(appId)){
			
			throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
		}
		int begin = page.getBeginIndex();
		
		int max = page.getMaxResultRecords();
		
		if(begin < 0 || max < 0 ){
			
			throw new CommonException(ErrorCode4AutorisedBillSketch.ERROR_BEGIN_OR_MAX_INVALID);
		}
		
		String todayUnpaidOutstandingBillApiName = ParticleModelConfigEnum.CONFIG_KEY_API_GET_TODAY_UNPAID_OUTSTANDING_BILLS.getAlias();
		
		String todayUnpaidOutstandingBillApiUrl = particalService.getQuarkApIUrl(particalUniqueId, todayUnpaidOutstandingBillApiName);
		
		logger.info("begin to get the today unpaid and oustanding bills with appId["+appId+"],begin["+begin+"],max=["+max+"],the api url["+todayUnpaidOutstandingBillApiUrl+"]");
		
		try {
		
			Response response = Jsoup.connect(todayUnpaidOutstandingBillApiUrl)
									 .method(Method.GET)
									 .data(ITodayUnpaidOutstandingBills.PARAM_APPID,appId)
									 .data(ITodayUnpaidOutstandingBills.PARAM_BEGIN,String.valueOf(begin))
									 .data(ITodayUnpaidOutstandingBills.PARAM_MAX,String.valueOf(max))
									 .timeout(TIMEOUT)
									 .execute();
			
			logger.info("get the today unpaid and outstanding bills result[" + response.body() + "]");
			
			Result result = JsonUtils.parse(response.body(), Result.class);
			
			List<AuthorisedBillSketch> authorisedBillSketchs = (List<AuthorisedBillSketch>) result.getData().get(ITodayUnpaidOutstandingBills.RET_BILLS);
			
			page.calculate(authorisedBillSketchs.size());
			
			return authorisedBillSketchs.size() > page.getEveryPage() ? authorisedBillSketchs.subList(0, page.getEveryPage()) : authorisedBillSketchs; 
			
		} catch (Exception e) {
			
			logger.info("get the today unpaid and outstanding bills error : " + e.getMessage());
			
			throw new CommonException(GeneralErrorCode.ERROR_SYSTEM);
		}
	}
	
	@Override
	public List<AuthorisedBillSketch> getOutstandingBills(
			String appId, String particalUniqueId,
			Page page) throws CommonException {
				
				if(StringUtils.isEmpty(appId)){
					
					throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
				}
				int begin = page.getBeginIndex(),max = page.getMaxResultRecords();
				
				if(begin < 0 || max < 0 ){
					
					throw new CommonException(ErrorCode4AutorisedBillSketch.ERROR_BEGIN_OR_MAX_INVALID);
				}
				
				String outstandingBillApiName = ParticleModelConfigEnum.CONFIG_KEY_API_GET_OUTSTANDING_BILLS.getAlias();
				
				String outstandingBillApiUrl = particalService.getQuarkApIUrl(particalUniqueId, outstandingBillApiName);
				
				logger.info("begin to get the outstanding bills with appId["+appId+"],begin["+begin+"],max=["+max+"],the api url["+outstandingBillApiUrl+"]");
				
				try {
				
					Response response = Jsoup.connect(outstandingBillApiUrl)
											 .method(Method.GET)
											 .data(IOutstandingBills.PARAM_APPID,appId)
											 .data(IOutstandingBills.PARAM_BEGIN,String.valueOf(begin))
											 .data(IOutstandingBills.PARAM_MAX,String.valueOf(max))
											 .timeout(TIMEOUT)
											 .execute();
					
					logger.info("get the outstanding bills result[" + response.body() + "]");
					
					Result result = JsonUtils.parse(response.body(), Result.class);
					
					List<AuthorisedBillSketch> authorisedBillSketchs = (List<AuthorisedBillSketch>) result.getData().get(IOutstandingBills.RET_BILLS);
					
					page.calculate(authorisedBillSketchs.size());
					
					return authorisedBillSketchs.size() > page.getEveryPage() ? authorisedBillSketchs.subList(0, page.getEveryPage()) : authorisedBillSketchs;
					
				} catch (Exception e) {
					
					logger.info("get the outstanding bills error : " + e.getMessage());
					
					throw new CommonException(GeneralErrorCode.ERROR_SYSTEM);
				}
	}

	@Override
	public List<TransactionRecordSketch> getTransactionRecord(String appId,
			String particalUniqueId, List<String> billIds)
			throws CommonException {
		
		if(StringUtils.isEmpty(appId)){
			
			throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
		}
		String getTransactionRecordApiName = ParticleModelConfigEnum.CONFIG_KEY_API_GET_TRANSACTION_RECORDS.getAlias();
		
		String getTransactionRecordApiUrl = particalService.getQuarkApIUrl(particalUniqueId, getTransactionRecordApiName);
		
		logger.info("begin to get the transaction record from quark with appId["+appId+"],the api url["+getTransactionRecordApiUrl+"],billIds["+billIds+"]");
		
		try {
		
			Response response = Jsoup.connect(getTransactionRecordApiUrl)
									 .method(Method.POST)
									 .data(ITransactionsFromBills.PARAM_BILL_IDS,JsonUtils.toJsonString(billIds))
									 .timeout(TIMEOUT)
									 .execute();
			
			logger.info("get the transaction record from bills result[" + response.body() + "]");
			
			Result result = JsonUtils.parse(response.body(), Result.class);
			
			if(result.getCode().equals(String.valueOf(GlobalCodeSpec.CODE_SUC))){
				
				return JsonUtils.parseArray(result.get(ITransactionsFromBills.RET_TRANSACTIONS).toString(), TransactionRecordSketch.class);
				
			}else{
				
				throw new CommonException(Integer.parseInt(result.getCode()));
			}
		} catch (Exception e) {
			
			logger.info("get the transaction record from bills : " + e.getMessage());
			
			throw new CommonException(GeneralErrorCode.ERROR_SYSTEM);
		}
	}

	@Override
	public boolean confirmTransactionRecord(String appId,
			String particalUniqueId, List<String> uniqueTransactionIds) throws CommonException {
		
		if(StringUtils.isEmpty(appId)){
			
			throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
		}
		String confirmTransactionRecordApiName = ParticleModelConfigEnum.CONFIG_KEY_API_CONFIRM_TRANSACTION_RECORDS.getAlias();
		
		String confirmTransactionRecordApiUrl = particalService.getQuarkApIUrl(particalUniqueId, confirmTransactionRecordApiName);
		
		logger.info("begin to cofirm the transaction record from quark with appId["+appId+"],the api url["+confirmTransactionRecordApiUrl+"],billIds["+uniqueTransactionIds+"]");
		
		try {
		
			Response response = Jsoup.connect(confirmTransactionRecordApiUrl)
									 .method(Method.POST)
									 .data(ITransactionConfirm.PARAM_TRANSACTION_IDS,JsonUtils.toJsonString(uniqueTransactionIds))
									 .timeout(TIMEOUT)
									 .execute();
			
			logger.info("get the confirm record from bills result[" + response.body() + "]");
			
			Result result = JsonUtils.parse(response.body(), Result.class);
			
			return String.valueOf(GlobalCodeSpec.CODE_SUC).equals(result.getCode());
			
		} catch (Exception e) {
			
			logger.info("confirm the transaction record from bills : " + e.getMessage());
			
			throw new CommonException(GeneralErrorCode.ERROR_SYSTEM);
		}
	}

	@Override
	public List<AuthorisedBillSketch> getOverPaymentDateBills(String appId,
			String particalUniqueId, Page page) throws CommonException {
		
		if(StringUtils.isEmpty(appId)){
			
			throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
		}
		int begin = page.getBeginIndex(),max = page.getMaxResultRecords();
		
		if(begin < 0 || max < 0 ){
			
			throw new CommonException(ErrorCode4AutorisedBillSketch.ERROR_BEGIN_OR_MAX_INVALID);
		}
		
		String getOverPaymentDateBillApiName = ParticleModelConfigEnum.CONFIG_KEY_API_GET_OVER_PAYMENTDATE_BILLS.getAlias();
		
		String getOverPaymentDateBillApiUrl = particalService.getQuarkApIUrl(particalUniqueId, getOverPaymentDateBillApiName);
		
		logger.info("begin to get the over payment date bills with appId["+appId+"],begin["+begin+"],max=["+max+"],the api url["+getOverPaymentDateBillApiUrl+"]");
		
		try {
		
			Response response = Jsoup.connect(getOverPaymentDateBillApiUrl)
									 .method(Method.GET)
									 .data(IOverPaymentDateBills.PARAM_APPID,appId)
									 .data(IOverPaymentDateBills.PARAM_BEGIN,String.valueOf(begin))
									 .data(IOverPaymentDateBills.PARAM_MAX,String.valueOf(max))
									 .timeout(TIMEOUT)
									 .execute();
			
			logger.info("get the over payment datebills result[" + response.body() + "]");
			
			Result result = JsonUtils.parse(response.body(), Result.class);
			
			List<AuthorisedBillSketch> authorisedBillSketchs = (List<AuthorisedBillSketch>) result.getData().get(IOverPaymentDateBills.RET_BILLS);
			
			page.calculate(authorisedBillSketchs.size());
			
			return authorisedBillSketchs.size() > page.getEveryPage() ? authorisedBillSketchs.subList(0, page.getEveryPage()) : authorisedBillSketchs;
			
		} catch (Exception e) {
			
			logger.info("get the over payment date bills error : " + e.getMessage());
			
			throw new CommonException(GeneralErrorCode.ERROR_SYSTEM);
		}
	}

	@Override
	public List<AuthorisedBillSketch> getNotReachPaymentDateBills(String appId,
			String particalUniqueId, Page page) throws CommonException {
		
		if(StringUtils.isEmpty(appId)){
			
			throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
		}
		int begin = page.getBeginIndex(),max = page.getMaxResultRecords();
		
		if(begin < 0 || max < 0 ){
			
			throw new CommonException(ErrorCode4AutorisedBillSketch.ERROR_BEGIN_OR_MAX_INVALID);
		}
		
		String getNotReachPaymentDateBillApiName = ParticleModelConfigEnum.CONFIG_KEY_API_GET_NOT_REACH_PAYMENTDATE_BILLS.getAlias();
		
		String getNotReachPaymentDateBillApiUrl = particalService.getQuarkApIUrl(particalUniqueId, getNotReachPaymentDateBillApiName);
		
		logger.info("begin to get the not reach payment date bills with appId["+appId+"],begin["+begin+"],max=["+max+"],the api url["+getNotReachPaymentDateBillApiUrl+"]");
		
		try {
		
			Response response = Jsoup.connect(getNotReachPaymentDateBillApiUrl)
									 .method(Method.GET)
									 .data(INotReachPaymentDateBills.PARAM_APPID,appId)
									 .data(INotReachPaymentDateBills.PARAM_BEGIN,String.valueOf(begin))
									 .data(INotReachPaymentDateBills.PARAM_MAX,String.valueOf(max))
									 .timeout(TIMEOUT)
									 .execute();
			
			logger.info("get the not reach payment date bills result[" + response.body() + "]");
			
			Result result = JsonUtils.parse(response.body(), Result.class);
			
			List<AuthorisedBillSketch> authorisedBillSketchs = (List<AuthorisedBillSketch>) result.getData().get(INotReachPaymentDateBills.RET_BILLS);
			
			page.calculate(authorisedBillSketchs.size());
			
			return authorisedBillSketchs.size() > page.getEveryPage() ? authorisedBillSketchs.subList(0, page.getEveryPage()) : authorisedBillSketchs;
			
		} catch (Exception e) {
			
			logger.info("get the not reach payment date bills error : " + e.getMessage());
			
			throw new CommonException(GeneralErrorCode.ERROR_SYSTEM);
		}
	}

	@Override
	public ReceivablesBrief getReceivablesBrief(String appId,
			String particalUniqueId) throws CommonException {
		
		if(StringUtils.isEmpty(appId)){
			//TODO CommonException.
			throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
		}
		String getReceivableBriefApiName = ParticleModelConfigEnum.CONFIG_KEY_API_GET_RECEIVABLE_BRIEF.getAlias();
		
		String getReceivableBriefApiUrl = particalService.getQuarkApIUrl(particalUniqueId, getReceivableBriefApiName);
		
		logger.info("begin to get the receivable statis  with appId["+appId+"],the api url["+getReceivableBriefApiUrl+"]");
		
		try {
		
			Response response = Jsoup.connect(getReceivableBriefApiUrl)
									 .method(Method.GET)
									 .data(IGetReceivablesBrief.PARAM_APPID,appId)
									 .timeout(TIMEOUT)
									 .execute();
			
			logger.info("get the receivable statis result[" + response.body() + "]");
			
			Result result = JsonUtils.parse(response.body(), Result.class);
			
			ReceivablesBrief receivableStatis =   JsonUtils.parse(result.get(IGetReceivablesBrief.RET_RECEIVABLES_BRIEF).toString(),ReceivablesBrief.class);
			
			return receivableStatis;
			
		} catch (Exception e) {
			
			logger.info("get the receivable statis error : " + e.getMessage());
			
			throw new CommonException(GeneralErrorCode.ERROR_SYSTEM);
		}
	}

	@Override
	public int getHistoryPaidOrderCount(String appId, String particalUniqueId,
			HistoryPaidType historyPaidType) {
		return orderService.getHistoryPaidOrderCountAtQuark(appId, particalUniqueId, historyPaidType);
	}


}
